package com.googlecode.jawb;

import java.util.Hashtable;

/**
 * Performance optimizer. Provides instances of data converters. Once some
 * converter has been created, it is stored to prevent being multiple
 * instantiated.
 */
public class ConverterFactory {
	/** All created instances of converters. */
	private Hashtable<Class<?>, Object> instancesPool = new Hashtable<>();

	/**
	 * Returns instance of requested converter. If such instance already exists,
	 * it will return this existing instance. In other case, new instance will
	 * be created and stored.
	 * 
	 * @param converterClass
	 *            Class (type) of requested converter.
	 * @return Instance of a given converter.
	 */
	public Object getInstance(Class<?> converterClass) {
		Object existingInstance = instancesPool.get(converterClass);
		
		if (existingInstance == null) {
			try {
				existingInstance = converterClass.newInstance();
				instancesPool.put(converterClass, existingInstance);
			} catch (IllegalAccessException e) {
				throw new RuntimeException(
					"Attempt to instantiate custom converter " + converterClass.getCanonicalName() + 
					"caused a violation of access policy.",
					e
				);
			} catch (InstantiationException e) {
				throw new RuntimeException(
					"Instance of a custom converter " + converterClass.getCanonicalName() + " could not be created. " +
					"This may be caused by missing non-parametric constructor",
					e
				);
			}
		}
		
		return existingInstance;
	}
}
